#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Datetime: 2020/09/22 17:43
# @Author  : CHEN Wang
# @Site    :
# @File    : stock_single_factor_analyse.py
# @Software: PyCharm

"""
脚本说明: 单因子分析脚本
"""


import numpy as np
import datetime as dt
from quant_researcher.quant.datasource_fetch.factor_api import factor_info, factor_exposure_related
from quant_researcher.quant.factors.factor_analysis.factor_analyser.factor_analyse import FactorAnalyseMachine
from quant_researcher.quant.datasource_fetch.common_data_api.t_trade_date import date_shifter_by_trade_date
from quant_researcher.quant.project_tool.db_operator import db_conn
from quant_researcher.quant.project_tool.logger.my_logger import LOG


def single_factor_analyse(factor_name, universe, begin_date, end_date, freq, group_num, weight_method, external_data=None):
    today = dt.datetime.today().strftime("%Y-%m-%d")
    if end_date == today:
        LOG.info('end_date为今天，查找上一个交易日')
        end_date = date_shifter_by_trade_date(end_date, how_many=1, before_or_after='before')
    else:
        end_date = end_date
    if external_data is not None:
        begin_date = external_data['tradedate'].min()
        end_date = external_data['tradedate'].max()
        machine = FactorAnalyseMachine(begin_date=begin_date, end_date=end_date,
                                       external_data=True, factor_data=external_data)
        machine.param_setting(period=freq, universe='', benchmark='000985')
    else:
        machine = FactorAnalyseMachine(factor_name, begin_date=begin_date, end_date=end_date)
        machine.param_setting(period=freq, universe=universe)
    machine.initial_data()
    ic_ir_result = machine.time_range_ic(period=freq, plot=False)
    ic_series = ic_ir_result[0].iloc[:, 0].rename('因子IC序列')
    cum_ic_series = ic_series.cumsum().rename('因子IC累计值')
    ic_stats = ic_ir_result[2].iloc[0]
    turnover = machine.factor_turnover_simple(period=freq, plot=False, winsor=False)
    _, _, performance, group_return = machine.longshort_portfolio(period=freq, group_num=group_num,weight_method=weight_method, plot=False)
    industry_group_ret = machine.get_stock_industry_group_return(group_num, plot=False)
    group_nav = (group_return+1).cumprod()-1
    group_nav.columns = ('分组' + group_nav.columns[:-1].astype(int).astype(str)).append(group_nav.columns[[-1]])
    performance = performance.replace({np.nan: ''})
    group_nav = group_nav.to_dict(orient='index')
    performance = performance.to_dict(orient='index')
    turnover_stats = (turnover.groupby(turnover.index.year).sum()).T
    turnover_stats['平均换手率'] = turnover_stats.mean(axis=1)
    turnover_stats['总换手率'] = turnover_stats.iloc[:,:-1].sum(axis=1)
    turnover_stats.columns = turnover_stats.columns.astype(str)
    turnover.index = turnover.index.strftime('%Y-%m-%d')
    turnover_stats = turnover_stats.to_dict(orient='index')
    turnover = turnover.to_dict(orient='index')
    ic_stats = ic_stats.to_dict()
    cum_ic_series = cum_ic_series.to_dict()
    ic_series = ic_series.to_dict()
    industry_group_ret = industry_group_ret.replace(np.nan, 0)
    industry_group_dict = dict()
    for industry in industry_group_ret['sw_ind1'].unique():
        industry_dict = industry_group_ret[industry_group_ret['sw_ind1']==industry][['group','cum_ret']].set_index('group')['cum_ret'].to_dict()
        industry_group_dict[industry] = industry_dict
    result = {'group_performance':performance, 'group_nav':group_nav,
              'factor_turnover':turnover, 'turnover_stats':turnover_stats,
              'ic_stats':ic_stats, 'ic_series':ic_series, 'cumulate_ic': cum_ic_series,
              'industry_group_ret':industry_group_dict}
    return result


if __name__ == '__main__':
    from quant_researcher.quant.datasource_fetch.index_api import index_components
    CON = db_conn.get_derivative_data_conn(by_sqlalchemy=True)
    CON_astk = db_conn.get_stock_conn(by_sqlalchemy=True)
    CON_factor = db_conn.get_tk_factors_conn(by_sqlalchemy=True)
    factor = 'rstr504'
    begin_date = '2020-12-12'
    end_date = '2021-01-12'
    asset_pool = index_components.get_index_hist_stock_pool('000300', begin_date, end_date)['stock_code'].tolist()
    factor_table_name = factor_info.get_factor_table_name(factor)[0]
    # temp = factor_exposure_related.get_stock_factor_exposure(factor, asset_pool, begin_date, end_date)
    temp = factor_exposure_related.get_stock_factor_exposure(factor, asset_pool, begin_date, end_date)
    temp = temp.rename(columns={'end_date': 'tradedate', 'stock_code': 'stockcode'})
    test = single_factor_analyse('arbr','HS300','2019-11-08', '2020-11-08', 'monthly', 5, '等权')
